package helper

import (
	"cloud-disk/core/define"
	"crypto/md5"
	"crypto/tls"
	"errors"
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/dgrijalva/jwt-go"
	"github.com/google/uuid"
	"github.com/jordan-wright/email"
	"math/rand"
	"net/http"
	"net/smtp"
	"os"
	"path"
	"time"
)

// MD5 加密，返回一个十六进制的MD5
func MD5(s string) string {
	return fmt.Sprintf("%X", md5.Sum([]byte(s)))
}

// GenerateToken 为当前用户生成一个Token
func GenerateToken(id int, identity, name string, second int) (string, error) {
	//id
	//identity
	//name
	uc := define.UserClaim{
		Id:             id,
		Identity:       identity,
		Name:           name,
		StandardClaims: jwt.StandardClaims{ExpiresAt: time.Now().Add(time.Second * time.Duration(second)).Unix()},
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, uc)
	tokenString, err := token.SignedString([]byte(define.JwtKey))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

// AnalyzeToken 解析Token
func AnalyzeToken(token string) (*define.UserClaim, error) {
	uc := new(define.UserClaim)
	claims, err := jwt.ParseWithClaims(token, uc, func(token *jwt.Token) (interface{}, error) {
		return []byte(define.JwtKey), nil
	})
	if err != nil {
		return nil, err
	}
	if !claims.Valid {
		return nil, errors.New("token is invalid")
	}
	return uc, nil
}

// MailCodeSend 邮箱验证码发送
func MailCodeSend(mail, code string) error {
	e := email.NewEmail()
	e.From = "Sender <1062966353@qq.com>"
	e.To = []string{mail}
	e.Subject = "验证码发送测试"
	e.HTML = []byte("你的验证码为: <h1>" + code + "</h1>，验证码将于五分钟后过期！")
	err := e.SendWithTLS("smtp.qq.com:465", smtp.PlainAuth("", "1062966353@qq.com", define.MailPassword(), "smtp.qq.com"),
		&tls.Config{InsecureSkipVerify: true, ServerName: "smtp.qq.com"})
	if err != nil {
		return err
	}
	return nil
}

// RandCode 生成随机验证码
func RandCode() string {
	s := "1234567890"
	code := ""
	rand.Seed(time.Now().UnixNano())
	for i := 0; i < define.CodeLength; i++ {
		code += string(s[rand.Intn(len(s))])
	}
	return code
}

// GetUUID 生成一个UUID
func GetUUID() string {
	return uuid.New().String()
}

// OSSUpload 将文件上传至OSS
func OSSUpload(r *http.Request) (string, error) {
	client, err := oss.New(define.Endpoint, define.OssAccessKeyId, define.OssAccessKeySecret)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	bucket, err := client.Bucket(define.Bucket)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 填写本地文件的完整路径
	file, fileHeader, err := r.FormFile("file")
	key := "cloud-disk/" + GetUUID() + path.Ext(fileHeader.Filename)
	if err != nil {
		return "", err
	}

	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}

	// 将文件流上传
	err = bucket.PutObject(key, file)
	if err != nil {
		fmt.Println("Error:", err)
		os.Exit(-1)
	}
	return define.AccessPrefix + key, nil
}
